<template lang="html">
    <div class="goods-sku">
        <dl v-for="item in goods.specs" :key="item.id">
            <dt>{{ item.name }}</dt>
            <dd>
              <template v-for="val in item.values" :key="val.name">
                <img v-if="val.picture" :src="val.picture" :class="{selected:val.selected}" @click="clickSpecs(item, val)" :title="val.name" alt="">
                <span :class="{selected:val.selected}" @click="clickSpecs(item, val)" v-else>{{ val.name }}</span>
              </template>
            </dd>
        </dl>
    </div>
</template>
<script> 
import PowerSet from '@/vender/power-set';
export default {
    name:'GoodsSku',
    props: {
      goods: {
        type: Object,
        default: () => ({
          specs:[], 
          skus:[]
        }),
      },
      skuId: {
        type:String, 
        default:''
      }
    },
    setup(props, {emit}) {
      const clickSpecs = (item, val) => {
        // 禁用状态
        if(val.disabled) return false


        // 切换选中状态
        if(val.selected) {
          val.selected = false
        }else {
          item.values.forEach(bv=>{bv.selected = false})
          val.selected = true
        }
      }
      // 路径字典
      const pathMap = getPathMap(props.goods.skus)

      // 根据skuId默认选中规格按钮
      initSelectedStatus(props.goods, props.skuId)

      updateDisabledStatus(props.goods.specs, pathMap)

      // 触发change事件将sku数据传递出去
      const selectedArr = getSelectedArr(props.goods.specs).filter(v=>v)
      if(selectedArr.length === props.goods.specs.length) {
        const skuIds = pathMap[selectedArr.join(spliter)]
        const sku = props.goods.skus.find(sku=>sku.id === skuIds[0])

        emit('change', {
          skuId:sku.id,
          price:sku.price,
          oldPrice:sku.oldPrice,
          inventory:sku.inventory,
          // reduce(callback, initialValue)
           specsText: sku.specs.reduce((p, n) => `${p} ${n.name}: ${n.valueName}`, '').replace(' ', '')
        })
      }

      return {
        clickSpecs,
        pathMap,
      }
    }
}

const spliter = '★'
// 根据获取的sku数据得到所有的路径
const getPathMap = (skus) => {
  const pathMap = {}
  skus.forEach(sku=>{
    // sku有库存
    if(sku.inventory) {
      // sku属性值的数组
      const specs = sku.specs.map(spec=>spec.valueName)
      // 得到sku属性值数组的子集

      const powerSet = PowerSet(specs)
      
      // 遍历幂集
      powerSet.forEach(set=> {
        // 使用spliter字符连接数组元素
        const key = set.join(spliter)
        // pathMap键值存在则添加值，不存在则创建键值对
        if(pathMap[key]) {
          pathMap[key].push(sku.id)
        }else {
          pathMap[key] = [sku.id]
        }
      })
    }
  })
  return pathMap
}

// 得到当前选中规格集合
const getSelectedArr = (specs) => {
  const selectedArr = []
  specs.forEach(spec => {
    const selectedVal = spec.values.find(val=>val.selected)
    selectedArr.push(selectedVal ? selectedVal.name : undefined)
  })

  return selectedArr
}

// 更新按钮禁用状态
const updateDisabledStatus = (specs, pathMap) => {
  specs.forEach((spec, index) => {
    const selectedArr = getSelectedArr(specs)
    spec.values.forEach(val=> {
      // 已被选中，不判断
      if(val.name === selectedArr[index]) return false
      // 未选中替换对应值
      selectedArr[index] = val.name
      // 过滤无效值得到key
      const key = selectedArr.filter(v=>v).join(spliter)

      // 禁用状态
      val.disabled = !pathMap[key]
    })
  })
}

// 初始化选中状态
const initSelectedStatus = (goods, skuId) => {
  const sku = goods.skus.find(sku=>sku.id===skuId)
  if(sku) {
    goods.specs.forEach((spec, index)=>{
      const value = sku.specs[index].valueName
      spec.values.forEach(val=> {
        val.selected = val.name === value
      })
    })
  }
}
</script>
<style lang="less" scoped>
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>